package com.evaluation.kexingcp.psycho.evaluation.sys.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.evaluation.kexingcp.admin.api.entity.SysDept;
import com.evaluation.kexingcp.admin.api.entity.SysUser;
import com.evaluation.kexingcp.admin.service.SysDeptService;
import com.evaluation.kexingcp.admin.service.SysUserService;
import com.evaluation.kexingcp.common.core.util.R;
import com.evaluation.kexingcp.common.excel.annotation.ResponseExcel;
import com.evaluation.kexingcp.common.log.annotation.SysLog;
import com.evaluation.kexingcp.psycho.evaluation.sys.entity.EvaluationInquiryRecordsEntity;
import com.evaluation.kexingcp.psycho.evaluation.sys.entity.EvaluationWarningFollowEntity;
import com.evaluation.kexingcp.psycho.evaluation.sys.entity.EvaluationWarningManualReviewEntity;
import com.evaluation.kexingcp.psycho.evaluation.sys.entity.EvaluationWarningRecordsEntity;
import com.evaluation.kexingcp.psycho.evaluation.sys.excels.BaseExcelExport;
import com.evaluation.kexingcp.psycho.evaluation.sys.service.*;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 预警跟进
 *
 * @author kexingcp
 * @date 2024-10-16 10:21:06
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/evaluationWarningFollow" )
@Tag(description = "evaluationWarningFollow" , name = "预警跟进管理" )
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class EvaluationWarningFollowController {

    private final EvaluationWarningFollowService evaluationWarningFollowService;
    private final EvaluationWarningManualReviewService evaluationWarningManualReviewService;
    private final SysUserService sysUserService;
    private final SysDeptService sysDeptService;
    private final EvaluationScaleService evaluationScaleService;
    private final EvaluationTaskService evaluationTaskService;
    private final EvaluationWarningRecordsService evaluationWarningRecordsService;

    /**
     * 分页查询
     * @param page 分页对象
     * @param evaluationWarningFollow 预警跟进
     * @return
     */
    @Operation(summary = "分页查询" , description = "分页查询" )
    @GetMapping("/page" )
    @PreAuthorize("@pms.hasPermission('admin_evaluationWarningFollow_view')" )
    public R getEvaluationWarningFollowPage(@ParameterObject Page page, @ParameterObject EvaluationWarningFollowEntity evaluationWarningFollow) {
        LambdaQueryWrapper<EvaluationWarningFollowEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.isNull(EvaluationWarningFollowEntity::getPid);
        wrapper.eq(!Objects.isNull(evaluationWarningFollow.getCompleted()), EvaluationWarningFollowEntity::getCompleted, evaluationWarningFollow.getCompleted());

        if (!Objects.isNull(evaluationWarningFollow.getUsername())) {
            List<SysUser> users = sysUserService.list(Wrappers.lambdaQuery(SysUser.class).like(SysUser::getName, evaluationWarningFollow.getUsername()));
            if (!users.isEmpty()) {
                wrapper.in(EvaluationWarningFollowEntity::getUserId, users.stream().map(SysUser::getUserId).toList());
            } else {
                return R.ok(Page.of(1,0,0));
            }
        }

        IPage<EvaluationWarningFollowEntity> list = evaluationWarningFollowService.page(page, wrapper);
        list.convert(this::setRecord);

        return R.ok(list);
    }

    private EvaluationWarningFollowEntity setRecord(EvaluationWarningFollowEntity record) {
        List<EvaluationWarningFollowEntity> arrayList = new ArrayList<>();
        EvaluationWarningFollowEntity cloned = new EvaluationWarningFollowEntity();
        BeanUtils.copyProperties(record, cloned);
        arrayList.add(cloned);
        arrayList.addAll(evaluationWarningFollowService.list(
                Wrappers.lambdaQuery(EvaluationWarningFollowEntity.class)
                        .eq(EvaluationWarningFollowEntity::getPid, record.getId())
                        .orderByAsc(EvaluationWarningFollowEntity::getCreateTime)));

        record.setRecords(arrayList);

        SysUser user = sysUserService.getById(record.getUserId());
        if (user != null) {
            user.setDeptList(sysDeptService.listParentDept(user.getDeptId()).stream().map(SysDept::getName).toList().reversed());
            record.setUser(user);
        }
        record.setScale(evaluationScaleService.getById(record.getScaleId()));
        record.setTask(evaluationTaskService.getById(record.getTaskId()));
        return record;
    }



    @GetMapping("/list" )
    public R list() {
        LambdaQueryWrapper<EvaluationWarningFollowEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.isNull(EvaluationWarningFollowEntity::getPid).eq(EvaluationWarningFollowEntity::getCompleted, false);
        List<EvaluationWarningFollowEntity> list = evaluationWarningFollowService.list(wrapper);
        return R.ok(list.stream().peek(record -> {

            List<EvaluationWarningFollowEntity> arrayList = new ArrayList<>();
            EvaluationWarningFollowEntity cloned = new EvaluationWarningFollowEntity();
            BeanUtils.copyProperties(record, cloned);
            arrayList.add(cloned);
            arrayList.addAll(evaluationWarningFollowService.list(
                    Wrappers.lambdaQuery(EvaluationWarningFollowEntity.class)
                            .eq(EvaluationWarningFollowEntity::getPid, record.getId())
                            .orderByAsc(EvaluationWarningFollowEntity::getCreateTime)));

            record.setRecords(arrayList);

//            SysUser user = sysUserService.getById(record.getUserId());
//            user.setDeptList(sysDeptService.listParentDept(user.getDeptId()).stream().map(SysDept::getName).toList().reversed());
//            record.setUser(user);
            record.setScale(evaluationScaleService.getById(record.getScaleId()));
            record.setTask(evaluationTaskService.getById(record.getTaskId()));
        }).toList());
    }


    /**
     * 通过id查询预警跟进
     * @param id id
     * @return R
     */
    @Operation(summary = "通过id查询" , description = "通过id查询" )
    @GetMapping("/{id}" )
    @PreAuthorize("@pms.hasPermission('admin_evaluationWarningFollow_view')" )
    public R getById(@PathVariable("id" ) Long id) {
        EvaluationWarningFollowEntity entity = evaluationWarningFollowService.getById(id);
        SysUser user = sysUserService.getById(entity.getUserId());
        user.setDeptList(sysDeptService.listParentDept(user.getDeptId()).stream().map(SysDept::getName).toList().reversed());
        entity.setUser(user);

        return R.ok(entity);
    }

    /**
     * 新增预警跟进
     * @param evaluationWarningFollow 预警跟进
     * @return R
     */
    @Operation(summary = "新增预警跟进" , description = "新增预警跟进" )
    @SysLog("新增预警跟进" )
    @PostMapping
    @PreAuthorize("@pms.hasPermission('admin_evaluationWarningFollow_add')" )
    public R save(@RequestBody EvaluationWarningFollowEntity evaluationWarningFollow) {
        if (evaluationWarningFollow.getManualReviewId() != null) {
            EvaluationWarningManualReviewEntity reviewEntity = evaluationWarningManualReviewService.getById(evaluationWarningFollow.getManualReviewId());
            evaluationWarningManualReviewService.removeById(evaluationWarningFollow.getManualReviewId());
            evaluationWarningFollow.setWarningSource(reviewEntity.getWarningSource());

            return R.ok(evaluationWarningFollowService.save(evaluationWarningFollow));
        }

        if (evaluationWarningFollow.getCompleted()) {
            EvaluationWarningFollowEntity entity = evaluationWarningFollowService.getById(evaluationWarningFollow.getPid());
            entity.setCompleted(true);
            evaluationWarningFollowService.updateById(entity);
        }

        return R.ok(evaluationWarningFollowService.save(evaluationWarningFollow));
    }

    /**
     * 修改预警跟进
     * @param evaluationWarningFollow 预警跟进
     * @return R
     */
    @Operation(summary = "修改预警跟进" , description = "修改预警跟进" )
    @SysLog("修改预警跟进" )
    @PutMapping
    @PreAuthorize("@pms.hasPermission('admin_evaluationWarningFollow_edit')" )
    public R updateById(@RequestBody EvaluationWarningFollowEntity evaluationWarningFollow) {
        return R.ok(evaluationWarningFollowService.updateById(evaluationWarningFollow));
    }

    /**
     * 通过id删除预警跟进
     * @param ids id列表
     * @return R
     */
    @Operation(summary = "通过id删除预警跟进" , description = "通过id删除预警跟进" )
    @SysLog("通过id删除预警跟进" )
    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('admin_evaluationWarningFollow_del')" )
    public R removeById(@RequestBody Long[] ids) {
        return R.ok(evaluationWarningFollowService.removeBatchByIds(CollUtil.toList(ids)));
    }


    /**
     * 导出excel 表格
     * @param evaluationWarningFollow 查询条件
   	 * @param ids 导出指定ID
     * @return excel 文件流
     */
    @GetMapping("/export")
    @PreAuthorize("@pms.hasPermission('admin_evaluationWarningFollow_export')" )
    public void export(HttpServletResponse response, EvaluationWarningFollowEntity evaluationWarningFollow,Long[] ids) throws IOException {
        List<EvaluationWarningFollowEntity> data = evaluationWarningFollowService.list(Wrappers.lambdaQuery(evaluationWarningFollow).isNull(EvaluationWarningFollowEntity::getPid).in(ArrayUtil.isNotEmpty(ids), EvaluationWarningFollowEntity::getId, ids));
        data = data.stream().map(this::setRecord).toList();
        EvaluationWarningFollowExport export = new EvaluationWarningFollowExport(response, List.of("姓名", "年龄", "性别",  "内容", "任务名称", "任务量表", "预警状态", "组织/单位"));
        export.doExport(data);
    }

    public static class EvaluationWarningFollowExport extends BaseExcelExport<EvaluationWarningFollowEntity> {
        public EvaluationWarningFollowExport(HttpServletResponse response, List<String> title) {
            super(response, title);
        }

        @Override
        protected void writeData(List<EvaluationWarningFollowEntity> data) {
            // 写入数据
            XSSFRow row;
            XSSFCell cell;
            for (int i = 0; i < data.size(); i++) {
                row = sheet.createRow(i + 1);
                for (String t : title) {
                    int j = ListUtils.indexOf(title, s -> StringUtils.equalsIgnoreCase(t, s));
                    cell = row.createCell(j);
                    if (StringUtils.equalsIgnoreCase(t, "姓名")) {
                        if (data.get(i).getUser() != null) {
                            cell.setCellValue(data.get(i).getUser().getName());
                        } else {
                            cell.setCellValue("用户已被删除,请删除此记录");
                        }
                    } else if (StringUtils.equalsIgnoreCase(t, "年龄")) {
                        if (data.get(i).getUser() != null) {
                            cell.setCellValue(data.get(i).getUser().getAge());
                        } else {
                            cell.setCellValue("用户已被删除,请删除此记录");
                        }
                    } else if (StringUtils.equalsIgnoreCase(t, "性别")) {
                        if (data.get(i).getUser() != null) {
                            cell.setCellValue(data.get(i).getUser().getSex());
                        } else {
                            cell.setCellValue("用户已被删除,请删除此记录");
                        }
                    } else if (StringUtils.equalsIgnoreCase(t, "任务名称")) {
                        if (data.get(i).getTask() != null) {
                            cell.setCellValue(data.get(i).getTask().getTaskName());
                        } else {
                            cell.setCellValue("任务已被删除,请删除此记录");
                        }
                    } else if (StringUtils.equalsIgnoreCase(t, "任务量表")) {
                        if (data.get(i).getScale() != null) {
                            cell.setCellValue(data.get(i).getScale().getScaleName());
                        } else {
                            cell.setCellValue("量表已被删除,请删除此记录");
                        }
                    } else if (StringUtils.equalsIgnoreCase(t, "预警状态")) {
                        // 设置文字颜色为红色
                        XSSFCellStyle cellStyle = workbook.createCellStyle();
                        XSSFFont font = workbook.createFont();
                        if (data.get(i).getCompleted()) {
                            font.setColor(IndexedColors.BLUE.index);
                            cell.setCellValue("已解除");
                        } else {
                            font.setColor(IndexedColors.RED.index);
                            cell.setCellValue("未解除");
                        }
                        cellStyle.setFont(font);
                        cell.setCellStyle(cellStyle);
                    } else if (StringUtils.equalsIgnoreCase(t, "组织/单位")) {
                        if (data.get(i).getUser() != null){
                            cell.setCellValue(data.get(i).getUser().getDeptList().stream().reduce((s1, s2) -> s1 + "/" + s2).orElse(""));
                        } else {
                            cell.setCellValue("用户已被删除,请删除此记录");
                        }
                    } else if (StringUtils.equalsIgnoreCase(t, "内容")) {
                        if (!data.get(i).getRecords().isEmpty()) {
                            List<EvaluationWarningFollowEntity> records = data.get(i).getRecords();
                            StringBuilder sb = new StringBuilder();
                            for (int k = 0; k < records.size(); k++) {
                                sb.append("第").append(k + 1).append("次:").append(records.get(k).getInquiryReason()).append("\n");
                            }
                            cell.setCellValue(sb.toString());
                        }
                    }
                }
            }
        }
    }
}